package cn.com.anypay.manager.common.utils;

import cn.com.anypay.manager.dto.config.WeChatAuthConfig;
import cn.com.anypay.manager.common.exception.WeChatAuthException;
import org.springframework.stereotype.Component;

import java.net.MalformedURLException;
import java.net.URL;
import java.util.regex.Pattern;

/**
 * 微信认证配置验证工具类
 * 用于验证微信认证相关配置的有效性
 */
@Component
public class WeChatConfigValidator {
    
    /**
     * 微信AppID格式正则表达式
     */
    private static final Pattern APPID_PATTERN = Pattern.compile("^wx[a-f0-9]{16}$");
    
    /**
     * 微信AppSecret格式正则表达式
     */
    private static final Pattern APP_SECRET_PATTERN = Pattern.compile("^[a-f0-9]{32}$");
    
    /**
     * 验证微信认证配置
     * 
     * @param config 微信认证配置
     * @throws WeChatAuthException 配置验证失败时抛出异常
     */
    public void validateConfig(WeChatAuthConfig config) throws WeChatAuthException {
        if (config == null) {
            throw WeChatAuthException.configError("微信认证配置不能为空");
        }
        
        // 验证是否启用
        if (config.getEnabled() == null || !config.getEnabled()) {
            throw WeChatAuthException.configError("微信认证功能未启用");
        }
        
        // 验证AppID
        validateAppId(config.getAppId());
        
        // 验证AppSecret
        validateAppSecret(config.getAppSecret());
        
        // 验证回调地址
        validateRedirectUri(config.getRedirectUri());
        
        // 验证授权作用域
        validateScope(config.getScope());
        
        // 验证超时时间
        validateTimeout(config.getTimeout());
        
        // 验证重试次数
        validateRetryCount(config.getRetryCount());
        
        // 验证状态参数有效期
        validateStateExpireSeconds(config.getStateExpireSeconds());
        
        // 验证API URL
        validateApiUrls(config);
    }
    
    /**
     * 验证AppID格式
     */
    private void validateAppId(String appId) throws WeChatAuthException {
        if (appId == null || appId.trim().isEmpty()) {
            throw WeChatAuthException.configError("微信AppID不能为空");
        }
        
        if (!APPID_PATTERN.matcher(appId.trim()).matches()) {
            throw WeChatAuthException.configError("微信AppID格式不正确，应为wx开头的18位字符串");
        }
    }
    
    /**
     * 验证AppSecret格式
     */
    private void validateAppSecret(String appSecret) throws WeChatAuthException {
        if (appSecret == null || appSecret.trim().isEmpty()) {
            throw WeChatAuthException.configError("微信AppSecret不能为空");
        }
        
        if (!APP_SECRET_PATTERN.matcher(appSecret.trim()).matches()) {
            throw WeChatAuthException.configError("微信AppSecret格式不正确，应为32位十六进制字符串");
        }
    }
    
    /**
     * 验证回调地址
     */
    private void validateRedirectUri(String redirectUri) throws WeChatAuthException {
        if (redirectUri == null || redirectUri.trim().isEmpty()) {
            throw WeChatAuthException.configError("微信授权回调地址不能为空");
        }
        
        try {
            URL url = new URL(redirectUri.trim());
            String protocol = url.getProtocol();
            
            // 生产环境必须使用HTTPS
            if (!"https".equals(protocol) && !"http".equals(protocol)) {
                throw WeChatAuthException.configError("微信授权回调地址协议不正确，必须使用HTTP或HTTPS");
            }
            
            // 检查域名是否为localhost或IP地址（开发环境允许）
            String host = url.getHost();
            if (host == null || host.trim().isEmpty()) {
                throw WeChatAuthException.configError("微信授权回调地址域名不能为空");
            }
            
        } catch (MalformedURLException e) {
            throw WeChatAuthException.configError("微信授权回调地址格式不正确: " + e.getMessage());
        }
    }
    
    /**
     * 验证授权作用域
     */
    private void validateScope(String scope) throws WeChatAuthException {
        if (scope == null || scope.trim().isEmpty()) {
            throw WeChatAuthException.configError("微信授权作用域不能为空");
        }
        
        String trimmedScope = scope.trim();
        if (!"snsapi_login".equals(trimmedScope) && !"snsapi_userinfo".equals(trimmedScope)) {
            throw WeChatAuthException.configError("微信授权作用域不正确，应为snsapi_login或snsapi_userinfo");
        }
    }
    
    /**
     * 验证超时时间
     */
    private void validateTimeout(Integer timeout) throws WeChatAuthException {
        if (timeout == null) {
            throw WeChatAuthException.configError("API调用超时时间不能为空");
        }
        
        if (timeout <= 0) {
            throw WeChatAuthException.configError("API调用超时时间必须大于0");
        }
        
        if (timeout > 60000) {
            throw WeChatAuthException.configError("API调用超时时间不能超过60秒");
        }
    }
    
    /**
     * 验证重试次数
     */
    private void validateRetryCount(Integer retryCount) throws WeChatAuthException {
        if (retryCount == null) {
            throw WeChatAuthException.configError("API调用重试次数不能为空");
        }
        
        if (retryCount < 0) {
            throw WeChatAuthException.configError("API调用重试次数不能小于0");
        }
        
        if (retryCount > 10) {
            throw WeChatAuthException.configError("API调用重试次数不能超过10次");
        }
    }
    
    /**
     * 验证状态参数有效期
     */
    private void validateStateExpireSeconds(Integer stateExpireSeconds) throws WeChatAuthException {
        if (stateExpireSeconds == null) {
            throw WeChatAuthException.configError("状态参数有效期不能为空");
        }
        
        if (stateExpireSeconds <= 0) {
            throw WeChatAuthException.configError("状态参数有效期必须大于0");
        }
        
        if (stateExpireSeconds > 3600) {
            throw WeChatAuthException.configError("状态参数有效期不能超过1小时");
        }
    }
    
    /**
     * 验证API URL
     */
    private void validateApiUrls(WeChatAuthConfig config) throws WeChatAuthException {
        validateUrl(config.getAuthUrl(), "微信授权URL");
        validateUrl(config.getTokenUrl(), "微信获取令牌URL");
        validateUrl(config.getUserInfoUrl(), "微信获取用户信息URL");
        validateUrl(config.getRefreshTokenUrl(), "微信刷新令牌URL");
    }
    
    /**
     * 验证URL格式
     */
    private void validateUrl(String url, String urlName) throws WeChatAuthException {
        if (url == null || url.trim().isEmpty()) {
            throw WeChatAuthException.configError(urlName + "不能为空");
        }
        
        try {
            new URL(url.trim());
        } catch (MalformedURLException e) {
            throw WeChatAuthException.configError(urlName + "格式不正确: " + e.getMessage());
        }
    }
    
    /**
     * 快速验证配置是否可用
     * 
     * @param config 微信认证配置
     * @return 配置是否可用
     */
    public boolean isConfigValid(WeChatAuthConfig config) {
        try {
            validateConfig(config);
            return true;
        } catch (WeChatAuthException e) {
            return false;
        }
    }
    
    /**
     * 获取配置验证错误信息
     * 
     * @param config 微信认证配置
     * @return 验证错误信息，如果配置有效则返回null
     */
    public String getConfigValidationError(WeChatAuthConfig config) {
        try {
            validateConfig(config);
            return null;
        } catch (WeChatAuthException e) {
            return e.getMessage();
        }
    }
}